#include "ConfigService.h"
#include "../db/DBPoll.h"
#include "../util/DateTime.h"
#include "../util/TextUtil.h"
#include "../common/Common.h"

// 数据表名称
#define SQL_DB_NAME_CONFIG	"t_config"

// 建表语句
#define SQL_CREATE_CONFIG	\
"CREATE TABLE IF NOT EXISTS `t_config` "\
"(`id` VARCHAR(64) NOT NULL comment '记录编码',"\
"`key` VARCHAR(32) default NULL comment '配置项目',"\
"`params` TEXT comment '配置参数',"\
"`enabled` TINYINT(1) default 1 comment '启用状态',"\
"`createTime` DATETIME default NULL comment '创建时间',"\
"`reserver1` VARCHAR(255) default NULL comment '保留字段1',"\
"`reserver2` VARCHAR(255) default NULL comment '保留字段2',"\
"primary key(`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统配置'"

#define SQL_CREATE_CONFIG2	\
"CREATE TABLE IF NOT EXISTS `t_config` "\
"(`id` VARCHAR(64) NOT NULL,"\
"`key` VARCHAR(32) default NULL,"\
"`params` TEXT,"\
"`enabled` TINYINT(1) default 1,"\
"`createTime` DATETIME default NULL,"\
"`reserver1` VARCHAR(255) default NULL,"\
"`reserver2` VARCHAR(255) default NULL,"\
"primary key(`id`))"

// 新增语句
#define SQL_INSERT_CONFIG \
"insert into t_config(`id`, `key`, `params`, `enabled`, `createTime`) values('%s', '%s', '%s', %d, '%s')"

// 删除语句
#define SQL_DELETE_CONFIG \
"delete from t_config where `id`='%s'"

// 查询语句
#define SQL_QUERY_CONFIG \
"select `id`, `key`, `params`, `enabled`, `createTime` from t_config where `id`='%s'"

#define SQL_QUERY_KEY \
"select `id`, `key`, `params`, `enabled`, `createTime` from t_config where `key`='%s'"

// 查询数量
#define SQL_QUERY_CONFIG_COUNT \
"select count(*) from t_config"

// 分页查询
#define SQL_QUERY_CONFIG_PAGE \
"select `id`, `key`, `params`, `enabled`, `createTime` from t_config limit %d, %d"

// 更新语句
#define SQL_UPDATE_CONFIG \
"update t_config set `key`='%s',`params`='%s', `enabled`=%d where `id`='%s'"

// 通过key更新
#define SQL_UPDATE_CONFIG_KEY \
"update t_config set `params`='%s', `enabled`=%d where `key`='%s'"

// 更新用户
#define SQL_UPDATE_ADMIN \
"update t_config set `params`='%s', `enabled`=1 where `key`='%s'"


ConfigService::ConfigService()
{
}

ConfigService::~ConfigService()
{
}

bool ConfigService::Exist()
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		bool ret = db->IsTableExist(SQL_DB_NAME_CONFIG);
		DBPoll::get_mutable_instance().Push(db);
		return ret;
	}
	return false;
}

bool ConfigService::Create()
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		std::string sql = db->GetDbType() == 0 ? SQL_CREATE_CONFIG : SQL_CREATE_CONFIG2;
		sql = TextUtil::get_mutable_instance().Ascii2Utf8(sql.c_str());
		bool ret = db->CreateTable(sql.c_str());
		DBPoll::get_mutable_instance().Push(db);
		return ret;
	}
	return false;
}

bool ConfigService::Add(ConfigInfo& item)
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		std::string sql = boost::str(boost::format(SQL_INSERT_CONFIG)
			% item.GetId() % item.GetKey() % item.GetParams()
			% item.GetEanble() % item.GetCreateTime().ToNormalString());

		uint64_t id = db->Insert(sql.c_str());
		DBPoll::get_mutable_instance().Push(db);
		if (0xffffffff == id)
		{
			return false;
		}
		return true;
	}
	return false;
}

bool ConfigService::AddAdmin(UserInfo& user)
{
	ConfigInfo config;
	config.SetId(TextUtil::get_mutable_instance().GetGuid());
	config.SetEanble(1);
	config.SetKey(CONFIG_TYPE_ADMIN);
	config.SetParams(user.ToJson());
	return Add(config);
}

bool ConfigService::Delete(ConfigInfo& item, bool delFromDB)
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		bool ret = false;
		if (delFromDB)
		{
			std::string sql = boost::str(boost::format(SQL_DELETE_CONFIG) % item.GetId());
			ret = db->Delete(sql.c_str());
		}

		DBPoll::get_mutable_instance().Push(db);
		return ret;
	}
	return false;
}

// 查询数量
int ConfigService::Count()
{
	int count = 0;
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		std::string sql = boost::str(boost::format(SQL_QUERY_CONFIG_COUNT));
		bool ret = db->Query(sql.c_str());
		if (ret)
		{
			if (db->FetchNextRow())
			{
				char* v = db->GetColValue(0);
				count = std::stoi(v);
			}
			db->FreeQueryResult();
		}
		DBPoll::get_mutable_instance().Push(db);
	}
	return count;
}

// 查找记录
bool ConfigService::FindPage(int pageIndex, int pageSize, std::vector<ConfigInfo>& list)
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		std::string sql = boost::str(boost::format(SQL_QUERY_CONFIG_PAGE) % pageIndex % pageSize);
		bool ret = db->Query(sql.c_str());
		if (ret)
		{
			while (db->FetchNextRow())
			{
				ConfigInfo item;
				ToRecord(db, item);
				list.push_back(item);
			}
			db->FreeQueryResult();
		}
		DBPoll::get_mutable_instance().Push(db);
		return ret;
	}
	return false;
}

bool ConfigService::Find(ConfigInfo& item)
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		std::string sql = boost::str(boost::format(SQL_QUERY_CONFIG) % item.GetId());
		bool ret = db->Query(sql.c_str());
		if (ret)
		{
			if (db->FetchNextRow())
			{
				ToRecord(db, item);
			}
			db->FreeQueryResult();
		}
		DBPoll::get_mutable_instance().Push(db);
		return ret;
	}
	return false;
}

bool ConfigService::FindByKey(ConfigInfo& item)
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		std::string sql = boost::str(boost::format(SQL_QUERY_KEY) % item.GetKey());
		bool ret = db->Query(sql.c_str());
		if (ret)
		{
			ret = false;
			if (db->FetchNextRow())
			{
				ToRecord(db, item);
				ret = true;
			}
			db->FreeQueryResult();
		}
		DBPoll::get_mutable_instance().Push(db);
		return ret;
	}
	return false;
}

bool ConfigService::FindAdmin(UserInfo& user)
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		std::string sql = boost::str(boost::format(SQL_QUERY_KEY) % CONFIG_TYPE_ADMIN);
		bool ret = db->Query(sql.c_str());
		if (ret)
		{
			ret = false;
			if (db->FetchNextRow())
			{
				ConfigInfo item;
				ToRecord(db, item);
				user.FromJson(item.GetParams());
				ret = true;
			}
			db->FreeQueryResult();
		}
		DBPoll::get_mutable_instance().Push(db);
		return ret;
	}
	return false;
}

bool ConfigService::Update(ConfigInfo& item)
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		std::string sql = boost::str(boost::format(SQL_UPDATE_CONFIG)
			% item.GetKey() % item.GetParams()
			% item.GetEanble() % item.GetId());
		bool ret = db->Update(sql.c_str());
		DBPoll::get_mutable_instance().Push(db);
		return ret;
	}
	return false;
}

bool ConfigService::UpdateByKey(ConfigInfo& item)
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		std::string sql = boost::str(boost::format(SQL_UPDATE_CONFIG_KEY)
			% item.GetParams()
			% item.GetEanble()
			% item.GetKey());
		bool ret = db->Update(sql.c_str());
		DBPoll::get_mutable_instance().Push(db);
		return ret;
	}
	return false;
}

bool ConfigService::UpdateAdmin(UserInfo& user)
{
	IDbBasePtr db = DBPoll::get_mutable_instance().Pop();
	if (db)
	{
		std::string info = user.ToJson();
		std::string sql = boost::str(boost::format(SQL_UPDATE_ADMIN) % info % CONFIG_TYPE_ADMIN);
		bool ret = db->Update(sql.c_str());
		DBPoll::get_mutable_instance().Push(db);
		return ret;
	}
	return false;
}

void ConfigService::ToRecord(IDbBasePtr db, ConfigInfo& item)
{
	std::string id = "";
	if (db->GetColValue(0))
	{
		id = db->GetColValue(0);
	}
	std::string key = "";
	if (db->GetColValue(1))
	{
		key = db->GetColValue(1);
	}
	std::string params = "";
	if (db->GetColValue(2))
	{
		params = db->GetColValue(2);
	}
	int enable = 0;
	if (db->GetColValue(3))
	{
		enable = atoi(db->GetColValue(3));
	}
	std::string time = "";
	if (db->GetColValue(4))
	{
		time = db->GetColValue(4);
	}

	item.SetId(id);
	item.SetKey(key);
	item.SetParams(params);
	item.SetEanble(enable);

	DateTime create_time;
	create_time.From(time);
	item.SetCreateTime(create_time);
}
